#include <iostream>
using namespace std;

void swap_value(int a, int b);           // 按值传递
void swap_pointer(int *a, int *b);       // 指针传递（传递指针）
void swap_reference(int &a, int &b);     // 按引用传递
void swap_pointer_ref(int *&a, int *&b); // 指针引用传递（传递指针的引用）

/*
| 函数名 | 参数类型 | 能否修改原始变量？ | 能否修改指针指向？ |
|-----------|---------|----------|---------|
| swap_value | 值传递 | ❌（仅修改副本） | 不涉及指针 |
| swap_pointer | 指针传递 | ✅（通过解引用修改值） | ❌（指针本身是副本） |
| swap_reference| 引用传递 | ✅（直接修改原始变量） | 不涉及指针 |
| swap_pointer_ref | 指针引用传递 | ❌（未修改指向的值） | ✅（通过引用修改指针指向）|
*/

int main()
{
    int a, b;

    a = 10;
    b = 20;
    swap_value(a, b);
    cout << "swap_value: a = " << a << ", b = " << b << endl;

    a = 10;
    b = 20;
    int *p = &a; // p指向a（地址）
    int *q = &b; // q指向b（地址）
    swap_pointer(p, q);
    cout << "swap_pointer: a = " << a << ", b = " << b << endl;     // a和b的值
    cout << "swap_pointer: *p = " << *p << ", *q = " << *q << endl; // p和q指向的值

    a = 10;
    b = 20;
    swap_reference(a, b);
    cout << "swap_reference: a = " << a << ", b = " << b << endl;

    a = 10;
    b = 20;
    p = &a; // p重新指向a
    q = &b; // q重新指向b
    swap_pointer_ref(p, q);
    cout << "swap_pointer_ref: a = " << a << ", b = " << b << endl;     // a和b的值
    cout << "swap_pointer_ref: *p = " << *p << ", *q = " << *q << endl; // p和q指向的值

    return 0;
}

// 按值传递
/*
原理：函数参数是实参的副本（拷贝），函数内部交换的是副本的值，不影响原始变量。
结果：a和b的值仍为10和20（未交换）。
*/
void swap_value(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
}

// 指针传递
/*
原理：函数参数是指针（地址）的副本，但通过指针的解引用（*）可以修改指针指向的原始变量的值。
结果：a和b的值被交换（变为20和10），因为函数内部通过*a和*b直接修改了p和q指向的内存空间（即a和b的实际地址）。
*/
void swap_pointer(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 按引用传递
/*
原理：函数参数是原始变量的引用（别名），操作引用等同于直接操作原始变量。
结果：a和b的值被交换（变为20和10），因为引用直接关联原始变量，无需解引用。
*/
void swap_reference(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

// 按指针引用传递
/*
原理：函数参数是指针的引用，即直接操作指针变量本身（而非指针指向的内容）。
结果：a和b的值不变（仍为10和20），但指针p和q的指向被交换：p现在指向b，q指向a。因此*p（b的值）为20，*q（a的值）为10。
*/
void swap_pointer_ref(int *&a, int *&b)
{
    int *temp = a;
    a = b;
    b = temp;
}